const express = require('express');
const cors = require('cors');
const compression = require('compression');
const helmet = require('helmet');
const morgan = require('morgan');
const path = require('path');
const fs = require('fs').promises;

const app = express();
const PORT = process.env.PORT || 3001;

// 中间件配置
app.use(helmet({
  crossOriginResourcePolicy: { policy: "cross-origin" }
}));
app.use(compression());
app.use(cors());
app.use(morgan('combined'));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// 静态文件服务 - 瓦片数据
app.use('/tiles', express.static(path.join(__dirname, 'tiles'), {
  maxAge: '1d',
  setHeaders: (res, filePath) => {
    if (filePath.endsWith('.png')) {
      res.setHeader('Content-Type', 'image/png');
      res.setHeader('Cache-Control', 'public, max-age=86400'); // 24小时缓存
    }
  }
}));

// 静态文件服务 - 矢量数据
app.use('/vector', express.static(path.join(__dirname, 'vector'), {
  maxAge: '1h',
  setHeaders: (res, filePath) => {
    if (filePath.endsWith('.json')) {
      res.setHeader('Content-Type', 'application/json');
      res.setHeader('Cache-Control', 'public, max-age=3600'); // 1小时缓存
    }
  }
}));

// 瓦片服务API
app.get('/api/tiles/:z/:x/:y.png', async (req, res) => {
  try {
    const { z, x, y } = req.params;
    
    // 验证参数有效性
    if (!isValidTileParams(z, x, y)) {
      return res.status(400).json({
        error: 'Invalid tile parameters',
        message: 'Zoom level, x, and y coordinates must be valid numbers'
      });
    }
    
    const tilePath = path.join(__dirname, 'tiles', z, x, `${y}.png`);
    
    try {
      // 检查文件是否存在
      await fs.access(tilePath);
      res.sendFile(tilePath);
    } catch (error) {
      res.status(404).json({
        error: 'Tile not found',
        message: `Tile at z=${z}, x=${x}, y=${y} does not exist`
      });
    }
  } catch (error) {
    console.error('Tile API error:', error);
    res.status(500).json({
      error: 'Internal server error',
      message: 'Failed to retrieve tile'
    });
  }
});

// 矢量数据服务API
app.get('/api/vector/:z/:x/:y.json', async (req, res) => {
  try {
    const { z, x, y } = req.params;
    
    // 验证参数有效性
    if (!isValidTileParams(z, x, y)) {
      return res.status(400).json({
        error: 'Invalid vector parameters',
        message: 'Zoom level, x, and y coordinates must be valid numbers'
      });
    }
    
    const vectorPath = path.join(__dirname, 'vector', z, x, `${y}.json`);
    
    try {
      // 检查文件是否存在
      await fs.access(vectorPath);
      res.sendFile(vectorPath);
    } catch (error) {
      res.status(404).json({
        error: 'Vector data not found',
        message: `Vector data at z=${z}, x=${x}, y=${y} does not exist`
      });
    }
  } catch (error) {
    console.error('Vector API error:', error);
    res.status(500).json({
      error: 'Internal server error',
      message: 'Failed to retrieve vector data'
    });
  }
});

// 健康检查端点
app.get('/health', (req, res) => {
  res.status(200).json({
    status: 'OK',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    memory: process.memoryUsage()
  });
});

// 瓦片参数验证函数
function isValidTileParams(z, x, y) {
  const zoom = parseInt(z);
  const tileX = parseInt(x);
  const tileY = parseInt(y);
  
  if (isNaN(zoom) || isNaN(tileX) || isNaN(tileY)) {
    return false;
  }
  
  // 检查缩放级别范围 (0-20)
  if (zoom < 0 || zoom > 20) {
    return false;
  }
  
  // 检查瓦片坐标范围
  const maxTile = Math.pow(2, zoom) - 1;
  if (tileX < 0 || tileX > maxTile || tileY < 0 || tileY > maxTile) {
    return false;
  }
  
  return true;
}

// 错误处理中间件
app.use((error, req, res, next) => {
  console.error('Unhandled error:', error);
  res.status(500).json({
    error: 'Internal server error',
    message: 'An unexpected error occurred'
  });
});

// 404处理
app.use('*', (req, res) => {
  res.status(404).json({
    error: 'Endpoint not found',
    message: `The requested endpoint ${req.originalUrl} does not exist`
  });
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`🚀 Map Tile Server is running on port ${PORT}`);
  console.log(`📊 Health check: http://localhost:${PORT}/health`);
  console.log(`🗺️  Tile API: http://localhost:${PORT}/api/tiles/{z}/{x}/{y}.png`);
  console.log(`📈 Vector API: http://localhost:${PORT}/api/vector/{z}/{x}/{y}.json`);
});

module.exports = app;